home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
051-075
/
disk_052
/
assign
/
assign.c
< prev
Wrap
C/C++ Source or Header
|
1992-05-06
|
11KB
|
310 lines
/*
* Assign Command - C Language Equivalent.
*
* This command looks and feels like the original AmigaDOS Assign command
* except that it is written in C and thus available for "forking." Also
* since it is written in C it is a somewhat larger than it's BCPL counterpart
* although a good assembly hack could probably fix that.
*
* (c) Copyright 1986 Charles McManis, All rights reserved.
* This code may be copied for private use only. It may not be
* included as part of any commercial package in whole or in
* part without the express written permission of the Author.
*
*/
#include <exec/types.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/filehandler.h>
#include <stdio.h>
extern struct DosLibrary *DOSBase;
#define PATHSIZE 128 /* This is max numbers in a path (Arbitrary) */
struct DosInfo *di;
struct FileInfoBlock *fi; /* Our file info (on directory assigns) */
char *pathstr, *tmpstr;
/*
* Function - MyExit(ConditionCode)
* This is the final exit routine, if we can't find something we need
* like memory we go here and free up what we have. Exit code is 'cc'.
*/
void MyExit(cc)
int cc;
{
if (fi != NULL) FreeMem(fi,sizeof(struct FileInfoBlock));
if (pathstr != NULL) FreeMem(pathstr,PATHSIZE);
if (tmpstr != NULL) FreeMem(tmpstr,PATHSIZE);
exit(cc);
}
/*
* Function - CvtBstr(str)
* This function takes a BPTR to a BSTR and returns a pointer to an
* equivalent C string that may be printed or copied.
*/
#define STRSIZE 81
char *
CvtBstr(bstr)
char *bstr;
{
int i,mx;
char *foo;
static char tmpstr[STRSIZE]; /* Maximum size */
foo = (char *)(BADDR(bstr));
mx = (foo[0] < STRSIZE) ? foo[0] : STRSIZE; /* Safety net */
for (i=0; i<mx; i++) tmpstr[i] = foo[i+1];
tmpstr[i] = '\0';
return(tmpstr);
}
/*
* Function - DeleteDevice(Name)
* This function will search the device list for a directory entry
* matching the one passed, and remove it from the device list.
*
* Returns 0 if successful.
*/
int
DeleteDevice(nm)
char *nm; /* String pointer to the Name */
{
struct DeviceList *prevdev,*thisdev;
char *str;
int i,found;
prevdev = NULL;
thisdev = (struct DeviceList *)BADDR(di->di_DevInfo);
found = -1;
while (thisdev != NULL) {
if (thisdev->dl_Type == DLT_DIRECTORY) {
str = CvtBstr(thisdev->dl_Name);
if (stricmp(str,nm) == 0) {
found = 0;
if (prevdev == NULL) { /* If first device */
Forbid(); /* Turn off tasking */
di->di_DevInfo = thisdev->dl_Next; /* Delete from list */
Permit(); /* Turn tasking back on */
}
else {
Forbid(); /* Turn off tasking */
prevdev->dl_Next = thisdev->dl_Next; /* Delete from list */
Permit(); /* Back to multitasking */
}
/* Now free the Lock, the String, and the DevList structure */
UnLock(thisdev->dl_Lock); /* free the lock */
str = (char *)(BADDR(thisdev->dl_Name)); /* easier to read */
i = str[0];
FreeMem(str,i); /* Free the string */
FreeMem(thisdev,sizeof(struct DeviceList)); /* Free struct */
break; /* Exit the while loop */
} /* if matched devices */
} /* if it was a directory entry */
prevdev = thisdev; /* If not found, walk the list */
thisdev = (struct DeviceList *)BADDR(thisdev->dl_Next);
} /* While */
return(found);
}
/*
* Main code, options of the Assign command are name, directory, or List.
* the default is to list the current assignments, Volumes, and devices.
*
*/
void main(argc,argv)
int argc; /* Number of arguments (max 3) */
char *argv[]; /* Text of the arguments */
{
/* The pointers here make it easier later */
struct RootNode *rn;
struct DeviceList *dl, *curdev, *xl;
struct DeviceNode *dn;
struct FileLock *fl;
BPTR plock, thislock, tb;
char Name[41],Path[81],*sptr;
int i,listem;
/* Get some memory for various buffers */
fi = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),0);
if (fi == NULL) MyExit(RETURN_FAIL);
pathstr = (char *)AllocMem(PATHSIZE,0);
if (pathstr == NULL) MyExit(RETURN_FAIL);
tmpstr = (char *)AllocMem(PATHSIZE,0);
if (tmpstr == NULL) MyExit(RETURN_FAIL);
printf("Assign command substitute v1.0\n");
/* Then we track down the head of the Device list from the Root Node */
rn = (struct RootNode *)DOSBase->dl_Root;
di = (struct DosInfo *)BADDR(rn->rn_Info);
/* dl becomes the anchor point that we always start from */
dl = (struct DeviceList *)BADDR(di->di_DevInfo);
listem = FALSE; /* Initially no list output */
Name[0] = '\0'; /* No name parameter */
Path[0] = '\0'; /* And no path specifier */
/*************************************************************************
* Process the arguments passed. To be 100% compatible with the AmigaDOS *
* assign command. *
*************************************************************************/
if (argc > 4) {
printf("Too many arguments, usage is Assign [Name:] [Dir:] [List]\n");
MyExit(RETURN_WARN);
}
for (i=1; i<argc; i++)
if (stricmp(argv[i],"LIST") == 0) listem = TRUE;
else if (Name[0] == '\0') strcpy(Name,argv[i]);
else if (Path[0] == '\0') strcpy(Path,argv[i]);
else {
printf("Bad Arguments, usage is Assign [Name:] [Dir:] [List]\n");
MyExit(RETURN_WARN);
}
if (strcmp(Name,"?") == 0) {
printf("Usage is Assign [Name:] [Dir:] [List]\n");
MyExit(RETURN_OK);
}
if (argc > 1) {
if ((sptr = (char *)strchr(Name,':')) == NULL) {
printf("Improper device name format.\n");
MyExit(RETURN_WARN);
}
*sptr = '\0'; /* Eliminate the trailing colon */
}
/* Ok, now we have the parameters they work like this, if a name was
* supplied but no path then it is a deassign operation, if both are
* supplied it is an assign operation, if both are missing it is a
* list operation
*/
if ((Name[0] != '\0') && (Path[0] == '\0')) /* DEASSIGN 'Name' */
if (DeleteDevice(Name) != 0) {
printf("Device %s: Not found.\n");
MyExit(RETURN_WARN);
}
if ((Name[0] != '\0') && (Path[0] != '\0')) { /* ASSIGN 'Name' */
(void) DeleteDevice(Name); /* Delete in case it exists */
if ((thislock = Lock(Path,ACCESS_READ)) != 0) {
dl = (struct DeviceList *)AllocMem(sizeof(struct DeviceList),0);
sptr = (char *)AllocMem(strlen(Name)+1,0);
strcpy(sptr+1,Name); /* Create BSTR out of Name */
*sptr = strlen(Name);
dl->dl_Name = (BSTR *)(((long)sptr) >> 2); /* Convert to BSTR ptr */
dl->dl_Lock = thislock; /* Put the BPTR value into Lock */
dl->dl_Type = DLT_DIRECTORY; /* The type is Directory */
fl = (struct FileLock *)(BADDR(thislock)); /* for convience */
dl->dl_Task = fl->fl_Task; /* Copy the message port task ptr */
tb = (BPTR)(((long)dl) >> 2); /* Make a BPTR out of our pointer */
Forbid(); /* Disable multitasking */
dl->dl_Next = di->di_DevInfo; /* Insert it at the head */
di->di_DevInfo = tb; /* Put a pointer to us in DevInfo */
Permit(); /* Start up Multitasking again */
} /* if we got the lock */
else {
printf("Couldn't get a Lock on %s\n",Path);
MyExit(RETURN_WARN);
}
} /* ASSIGN operation */
if (((Name[0] != '\0') || (Path[0] != '\0')) && ! listem) MyExit(RETURN_OK);
/* The remainder of the code lists out the current assignments, if
* no arguments, or the argument "List" is included it will run this
* section.
*
* Pass 1: Print out all of the known volumes, if they have a handler
* task present then they are mounted in a physical device
*/
curdev = dl;
printf("Volumes:\n");
while (curdev != NULL) {
if (curdev->dl_Type == DLT_VOLUME) {
printf("%s ",CvtBstr(curdev->dl_Name));
if (curdev->dl_Task != NULL) printf("[Mounted]");
printf("\n");
}
curdev = (struct DeviceList *)BADDR(curdev -> dl_Next);
}
printf("\n");
/* Pass 2 : Scan for directory redirections. If the volume that the
* directory is redirected to is not mounted then we just
* print out the volume name. If it is mounted we print
* out the full path. If we have been redirected to a device
* like 'RAM' then we just print the device name.
*/
curdev = dl;
printf("Directories:\n");
while (curdev != NULL) {
if (curdev->dl_Type == DLT_DIRECTORY) {
strcpy(tmpstr,CvtBstr(curdev->dl_Name));
printf("%s ",tmpstr);
if (strlen(tmpstr) < 8) printf(" ");
fl = (struct FileLock *)(BADDR(curdev->dl_Lock));
xl = (struct DeviceList *)(BADDR(fl->fl_Volume));
if (xl->dl_Type == DLT_DEVICE) {
dn = (struct DeviceNode *) xl;
printf("%s:",CvtBstr(dn->dn_Name));
}
else {
if (xl->dl_Task == NULL) /* Not Mounted if Task == NULL */
printf("Volume: %s",CvtBstr(xl->dl_Name));
else { /* This code tracks down the full path */
printf("%s:",CvtBstr(xl->dl_Name));
pathstr[0] = '\0'; /* initialize it to the null string */
thislock = curdev->dl_Lock;
plock = ParentDir(thislock);
while (plock != 0) {
if (Examine(thislock,fi)) {
if (strlen(pathstr) == 0) strcpy(pathstr,fi->fib_FileName);
else {
strins(pathstr,"/"); /* insert directory separator */
strins(pathstr,fi->fib_FileName); /* insert parent dir name */
}
}
else printf("\nBad Lock!\n"); /* This should never print! */
thislock = plock;
plock = ParentDir(thislock);
} /* while we haven't got to the top */
printf("%s",pathstr);
}
} /* else it was a directory rather than a device */
printf("\n");
} /* If it was a directory redirection at all */
curdev = (struct DeviceList *)BADDR(curdev -> dl_Next);
}
printf("\n");
/* Pass 3 : Print out all of the devices, like the original we pretty much
* assume device names are three characters long. (They can be more
* though.)
*/
printf("Devices:");
i = 0;
curdev = dl;
while (curdev != NULL) {
if (curdev->dl_Type == DLT_DEVICE) {
if ((i%5) == 0) printf("\n"); /* Every 5 devices print a newline */
i++;
dn = (struct DeviceNode *) curdev;
printf("%s ",CvtBstr(dn->dn_Name));
}
curdev = (struct DeviceList *)BADDR(curdev -> dl_Next);
} /* While */
printf("\n");
MyExit(RETURN_OK); /* Exit with a status of zero */
}